package tjs.study.notes.dotest.jvm.heap;

/**
 * Created by Nicky.Tang on 2021/10/13 11:05 上午
 *
 * @since 02.12.10
 */
public class 重复引用 {
    /**
     * -XX:+PrintGCDetails -Xms3m -Xmx3m
     *
     * @param args
     */
    public static void main(String[] args) throws InterruptedException {
//        doOther();
//        UserServiceA userServiceA = new UserServiceA();
//        UserServiceB userServiceB = new UserServiceB();
//        doTest();

//        byte[] array1 = new byte[1024*1024];
        /**
         *  array1=null;//因为当前main的栈还没有结束，
         *  当前main方法栈帧的局部变量表依然还存在array1的引用，
         *  所以如果不强制置为null，是无法被回收的
         */
//        doTest2();
        Integer a=2;
        if(a==2){
//        if(1==1){//这种判断，会被jvm优化去除掉
            UserServiceA userServiceA = new UserServiceA();
            //userServiceA=null;//不放开这段，直接gc，userServiceA依然会被回收
        }
        Thread.currentThread().sleep(2000);
        System.gc();
        Thread.currentThread().sleep(999999);
    }

    public static void doTest2() {
        byte[] array1 = new byte[1024 * 1024];
        //array1=null;;//方法调用结束后，因为当前doTest2的栈已经结束，
        //当前doTest2方法栈已经被清楚了，所以不强制置为null，也是会被回收的
    }


    public static void doTest() {
        UserServiceA userServiceA = new UserServiceA();
        UserServiceB userServiceB = new UserServiceB();
        userServiceA.otherService = userServiceB;
        userServiceB.otherService = userServiceA;

        // do some other thing
        userServiceA = null;
        userServiceB = null;//方法调用结束后，
        // 根据可达性分析算法可知，起始节点已经没了，置不置为null，都会被回收
    }

    public static void doOther() {
        UserServiceA userServiceA = new UserServiceA();
        UserServiceA userServiceA2 = userServiceA;
        userServiceA = null;
        System.out.println(userServiceA2 == null);//false
    }

    static class UserServiceA {
        private byte[] array1 = new byte[1024 * 1024];
        private Object otherService;
    }

    static class UserServiceB {
        private byte[] array1 = new byte[1024 * 1024];
        private Object otherService;
    }
}
